酒后写代码,我删了生产数据库…
The following article is from 程序员的那些事 Author 程序员的那些事
“如果早上喝咖啡都还不能让脑子清醒,那就到生产环境删表吧!”
老读者可能还记得我们在 2017 年 11 月发过的这个趣图。
不过类似的技术八卦呢,的确发生了,而且还上过新闻了。
2020 年 10 月 12 日,国外一个记分服务 keepthescore 在推特上发了和本文开头一样的趣图。
没过几天,keepthescore 就出现了生产环境删库事件。真是一语成谶啊
这到底是一个怎么样的瓜?
17 日 keepthescore 官博更新了一篇文章,做出了解释。
“(当地时间)晚上 10:45 左右,几杯红酒下肚后,我们在生产环境无意删库了。超过 300.00 分及其数据瞬间灰飞烟灭。” (当事人应该瞬间醒酒了
“不过谢天谢地,我们服务器托管商 DigitalOcean 每天会自动备份一次。经过 5 分钟的绝望和恐慌后,我们进入了网站维护模式,并开始恢复备份。灾难发生 30 分钟后,恢复了备份数据,网站重新上线,但是 7 个小时的数据永久丢失了!
为什么会出现删库?
“谁叫你们喝酒后还写代码啊”。也许大家会归咎于那几杯红酒。
然而,删除数据库的函数是他们程序员之前清醒时编写的。那个函数删除本地数据库,然后从头创建所有所需的表。
17 日晚上写代码的时候,该函数连接到生产数据库并擦除它。为什么会删?他们也还没搞明白。
下面就是引发本次删库灾难的代码:
def database_model_create():
"""Only works on localhost to prevent catastrophe"""
database = config.DevelopmentConfig.DB_DATABASE
user = config.DevelopmentConfig.DB_USERNAME
password = config.DevelopmentConfig.DB_PASSWORD
port = config.DevelopmentConfig.DB_PORT
local_db = PostgresqlDatabase(database=database, user=user, password=password, host='localhost', port=port)
local_db.drop_tables([Game, Player, Round, Score, Order])
local_db.create_tables([Game, Player, Round, Score, Order])
print('Initialized the local database.')
请注意,host 是硬编码写了 localhost 的。
这意味着它不应该连接到开发者机器之外的其他机器。不过他们在开发和生产中使用不同的密码和用户。他们在文中表示,“太累了,现在都想不出来为什么。”
他们从中学到了哪些教训?
他们已经学到了:
1、有可删除数据库的函数是非常危险的。永远不能真正正确地测试安全机制,因为想测试就意味着要拿生产数据库开刀。
2、必须要有能够快速恢复的备份。
3、即使是灾难也有好的一面。他们那篇博客文章引起了很多人的兴趣,给大家乐趣和警醒。
涉事程序员被老板开除了么?
没有开除。因为 keepthescore 的删库开发者和创始人都是同一人,名字叫 Caspar。「程序员的那些事」有理由怀疑,keepthescore 的保安、市场和运营等岗位,也是由 Caspar 在做。
Caspar 表示,这是他的一个副项目,虽然不是电厂运行的那个级别的软件,但用户中也有部分付费的,他表示深深的歉意。
Caspar 心态很是挺不错的,他在博文最后把自己前几天发的趣图贴了出来,让大家一起从欢乐中吸取教训。
这种事还会再发生么?
Caspar 坦言,“我们无法百分之百保证这种事情不会再次发生。计算机实在是太复杂了,总有一天复杂的小妖精会赢。但是,我们将找出问题所在,并确保这个特定的错误不会再次发生。”
关于预防在生产环境出现删库事件,大家有什么好的建议呢?欢迎留言分享。
- EOF -
看完本文有收获?请分享给更多人
推荐关注「Linux 爱好者」,提升Linux技能
点赞和在看就是最大的支持❤️